﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IronLua.Metadata
{
    public sealed class Prototype
    {
        internal static readonly Prototype HostPrototype = Prototype.FromClrFunction("?", (t) => -1);

        internal static readonly IList<Instruction> emptyInstructionList = new List<Instruction>().AsReadOnly();
        internal static readonly IList<UpValue> emptyUpValueList = new List<UpValue>().AsReadOnly();
        internal static readonly IList<Constant> emptyConstantList = new List<Constant>().AsReadOnly();
        internal static readonly IList<Prototype> emptyProtoList = new List<Prototype>().AsReadOnly();
        internal static readonly IList<Local> emptyLocalList = new List<Local>().AsReadOnly();
        internal static readonly IList<int> emptyLineList = new List<int>().AsReadOnly();

        internal static Prototype FromClrFunction(string name, ClrPrototype clrproto)
        {
            return new Prototype()
            {
                Name = name,
                ClrPrototype = clrproto,
                Kind = PrototypeKind.IL,
                Instructions = Prototype.emptyInstructionList,
                UpValueMetadata = Prototype.emptyUpValueList,
                VarArgFlags = VarArgFlags.IsVarArg,
                Constants = Prototype.emptyConstantList,
                Prototypes = Prototype.emptyProtoList,
                LocalsMetadata = Prototype.emptyLocalList,
                SourceLines = Prototype.emptyLineList,
            };
        }

        internal Prototype()
        {
        }

        public string               Name { get; internal set; }
        public uint                 Depth { get; internal set; }
        public uint                 Index { get; internal set; }
        public uint                 LineDefined { get; internal set; }
        public uint                 LastLineDefined { get; internal set; }
        public uint                 ParameterCount { get; internal set; }
        public IList<Instruction>   Instructions { get; internal set; }
        public IList<UpValue>       UpValueMetadata { get; internal set; }
        public VarArgFlags          VarArgFlags { get; internal set; }
        public uint                 StackSize { get; internal set; }
        public IList<Constant>      Constants { get; internal set; }
        public IList<Prototype>     Prototypes { get; internal set; }
        public IList<Local>         LocalsMetadata { get; internal set; }
        public IList<int>           SourceLines { get; internal set; }

        internal PrototypeKind      Kind { get; set; }
        internal ClrPrototype       ClrPrototype { get; set; }  
    }
}
